#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
测试运行脚本

提供便捷的测试执行命令，支持不同类型的测试运行。

使用方法:
    python run_tests.py --help
    python run_tests.py --unit
    python run_tests.py --integration
    python run_tests.py --performance
    python run_tests.py --all
"""

import os
import sys
import argparse
import subprocess
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))


class TestRunner:
    """测试运行器"""
    
    def __init__(self):
        self.test_dir = Path(__file__).parent
        self.project_root = self.test_dir.parent
        
    def run_command(self, cmd, description=""):
        """运行命令并处理结果"""
        print(f"\n{'='*60}")
        print(f"执行: {description}")
        print(f"命令: {' '.join(cmd)}")
        print(f"{'='*60}")
        
        try:
            result = subprocess.run(cmd, cwd=self.project_root, check=True, 
                                  capture_output=False, text=True)
            print(f"\n✓ {description} 执行成功")
            return True
        except subprocess.CalledProcessError as e:
            print(f"\n✗ {description} 执行失败: {e}")
            return False
        except FileNotFoundError:
            print(f"\n✗ 命令未找到，请确保已安装pytest")
            return False
    
    def setup_environment(self):
        """设置测试环境"""
        # 检查.env.test文件
        env_test_file = self.test_dir / '.env.test'
        env_file = self.project_root / '.env'
        
        if env_test_file.exists() and not env_file.exists():
            print(f"提示: 发现测试环境配置文件 {env_test_file}")
            print(f"建议复制为 {env_file} 并根据实际环境修改")
        
        # 创建日志目录
        log_dir = self.test_dir / 'logs'
        log_dir.mkdir(exist_ok=True)
        
        # 创建覆盖率报告目录
        coverage_dir = self.test_dir / 'coverage_html'
        coverage_dir.mkdir(exist_ok=True)
    
    def run_unit_tests(self):
        """运行单元测试"""
        cmd = [
            'python', '-m', 'pytest',
            str(self.test_dir / 'test_android_client_data_flow.py::TestAndroidClientDataFlow'),
            '-m', 'not slow',
            '--tb=short',
            '-v'
        ]
        return self.run_command(cmd, "单元测试")
    
    def run_integration_tests(self):
        """运行集成测试"""
        cmd = [
            'python', '-m', 'pytest',
            str(self.test_dir / 'test_android_client_data_flow.py::TestDataValidation'),
            '-m', 'integration or database',
            '--tb=short',
            '-v'
        ]
        return self.run_command(cmd, "集成测试")
    
    def run_performance_tests(self):
        """运行性能测试"""
        cmd = [
            'python', '-m', 'pytest',
            str(self.test_dir / 'test_android_client_data_flow.py'),
            '-m', 'performance',
            '--tb=short',
            '-v',
            '--benchmark-only'
        ]
        return self.run_command(cmd, "性能测试")
    
    def run_all_tests(self):
        """运行所有测试"""
        cmd = [
            'python', '-m', 'pytest',
            str(self.test_dir / 'test_android_client_data_flow.py'),
            '--tb=short',
            '-v',
            '--cov=.',
            '--cov-report=html:tests/coverage_html',
            '--cov-report=term-missing'
        ]
        return self.run_command(cmd, "所有测试")
    
    def run_specific_test(self, test_name):
        """运行特定测试"""
        cmd = [
            'python', '-m', 'pytest',
            str(self.test_dir / 'test_android_client_data_flow.py'),
            '-k', test_name,
            '--tb=short',
            '-v'
        ]
        return self.run_command(cmd, f"特定测试: {test_name}")
    
    def run_with_coverage(self):
        """运行测试并生成覆盖率报告"""
        cmd = [
            'python', '-m', 'pytest',
            str(self.test_dir / 'test_android_client_data_flow.py'),
            '--cov=models',
            '--cov=service',
            '--cov=config',
            '--cov-report=html:tests/coverage_html',
            '--cov-report=term-missing',
            '--cov-fail-under=70',
            '-v'
        ]
        success = self.run_command(cmd, "测试覆盖率分析")
        
        if success:
            coverage_file = self.test_dir / 'coverage_html' / 'index.html'
            if coverage_file.exists():
                print(f"\n📊 覆盖率报告已生成: {coverage_file}")
        
        return success
    
    def check_dependencies(self):
        """检查测试依赖"""
        print("检查测试依赖...")
        
        required_packages = [
            'pytest',
            'pytest-asyncio',
            'pytest-cov',
            'psutil'
        ]
        
        missing_packages = []
        
        for package in required_packages:
            try:
                __import__(package.replace('-', '_'))
                print(f"✓ {package}")
            except ImportError:
                missing_packages.append(package)
                print(f"✗ {package} (未安装)")
        
        if missing_packages:
            print(f"\n缺少依赖包: {', '.join(missing_packages)}")
            print(f"请运行: pip install {' '.join(missing_packages)}")
            return False
        
        print("\n✓ 所有测试依赖已满足")
        return True
    
    def show_test_info(self):
        """显示测试信息"""
        print("\n📋 测试文件信息:")
        print(f"  主测试文件: {self.test_dir / 'test_android_client_data_flow.py'}")
        print(f"  配置文件: {self.test_dir / 'pytest.ini'}")
        print(f"  环境配置: {self.test_dir / '.env.test'}")
        
        # 统计测试用例数量
        try:
            result = subprocess.run([
                'python', '-m', 'pytest', 
                str(self.test_dir / 'test_android_client_data_flow.py'),
                '--collect-only', '-q'
            ], cwd=self.project_root, capture_output=True, text=True)
            
            if result.returncode == 0:
                lines = result.stdout.strip().split('\n')
                test_count = len([line for line in lines if 'test_' in line])
                print(f"  测试用例数量: {test_count}")
        except:
            print("  测试用例数量: 无法统计")


def main():
    parser = argparse.ArgumentParser(description='Android客户端数据流测试运行器')
    parser.add_argument('--unit', action='store_true', help='运行单元测试')
    parser.add_argument('--integration', action='store_true', help='运行集成测试')
    parser.add_argument('--performance', action='store_true', help='运行性能测试')
    parser.add_argument('--all', action='store_true', help='运行所有测试')
    parser.add_argument('--coverage', action='store_true', help='运行测试并生成覆盖率报告')
    parser.add_argument('--check-deps', action='store_true', help='检查测试依赖')
    parser.add_argument('--info', action='store_true', help='显示测试信息')
    parser.add_argument('--test', type=str, help='运行特定测试（按名称匹配）')
    
    args = parser.parse_args()
    
    runner = TestRunner()
    runner.setup_environment()
    
    # 如果没有指定任何参数，显示帮助信息
    if not any(vars(args).values()):
        parser.print_help()
        runner.show_test_info()
        return
    
    success = True
    
    if args.check_deps:
        success = runner.check_dependencies()
    
    if args.info:
        runner.show_test_info()
    
    if args.unit:
        success = runner.run_unit_tests() and success
    
    if args.integration:
        success = runner.run_integration_tests() and success
    
    if args.performance:
        success = runner.run_performance_tests() and success
    
    if args.all:
        success = runner.run_all_tests() and success
    
    if args.coverage:
        success = runner.run_with_coverage() and success
    
    if args.test:
        success = runner.run_specific_test(args.test) and success
    
    if success:
        print("\n🎉 所有测试执行完成")
        sys.exit(0)
    else:
        print("\n❌ 测试执行过程中出现错误")
        sys.exit(1)


if __name__ == '__main__':
    main()